#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time   : 2023-11-26 15:09
# @Author : hard work
# @File    : renix_RFC2544.py
# @Description :
from common.renix_basic_config.renix_config import renix_config
from traffic_tool.tool_renix.renix_empty.renix_basic_empty import Renix_basic_config
from renix_py_api.api_gen import *

from renix_py_api.renix import *

from renix_py_api.benchmark_test.benchmark_test_api import *


class Renix_RFC2889(Renix_basic_config):
    def __init__(self, **kwargs):
        super().__init__()
        if renix_config():
            """使用配置文件(../common/renix_basic_config/renix_config.py)中的配置"""
            Renix_basic_config.chassis_address = renix_config()['chassis_address']
            Renix_basic_config.slot = renix_config()['slot']
            Renix_basic_config.port1 = renix_config()['port1']
            Renix_basic_config.port2 = renix_config()['port2']
            Renix_basic_config.port3 = renix_config()['port3']
            Renix_basic_config.port4 = renix_config()['port4']
            Renix_basic_config.port5 = renix_config()['port5']
            Renix_basic_config.renix_install_addr = renix_config()['renix_install_addr']
        else:
            """使用自定义配置"""
            if not kwargs:
                return
            # 如果不使用默认配置，此处修改你自己的配置
            Renix_basic_config.chassis_address = kwargs['chassis_address']
            Renix_basic_config.slot = kwargs['slot']
            Renix_basic_config.port1 = kwargs['port1']
            Renix_basic_config.port2 = kwargs['port2']
            Renix_basic_config.port3 = kwargs['port3']
            Renix_basic_config.port4 = kwargs['port4']
            Renix_basic_config.port5 = kwargs['port5']
            Renix_basic_config.renix_install_addr = kwargs['renix_install_addr']
        # Renix_basic_config().set_renix_SysVariable()
        self.chassis = None
        self.Port_1 = None
        self.Port_2 = None
        self.Port_3 = None
        self.Port_4 = None
        self.sys_entry = None

    def set_renix_rfc2889_start(self, save_result_file):
        initialize()
        self.sys_entry = get_sys_entry()
        self.Port_1 = Port(upper=self.sys_entry, Location='//%s/%s/%s' % (self.chassis_address, self.slot, self.port1))
        self.Port_2 = Port(upper=self.sys_entry, Location='//%s/%s/%s' % (self.chassis_address, self.slot, self.port2))
        self.Port_3 = Port(upper=self.sys_entry, Location='//%s/%s/%s' % (self.chassis_address, self.slot, self.port3))
        self.Port_4 = Port(upper=self.sys_entry, Location='//%s/%s/%s' % (self.chassis_address, self.slot, self.port4))

        bring_port_online_cmd = BringPortsOnlineCommand(
            PortList=[self.Port_1.handle, self.Port_2.handle, self.Port_3.handle, self.Port_4.handle])

        bring_port_online_cmd.execute()

        interface1 = Interface(upper=self.Port_1)

        interface2 = Interface(upper=self.Port_2)

        interface3 = Interface(upper=self.Port_3)

        interface4 = Interface(upper=self.Port_4)

        build_ipv4_interface = BuildInterfaceCommand(
            InterfaceList=[interface1.handle, interface2.handle, interface3.handle, interface4.handle],
            NetworkLayers=['eth', 'ipv4'])

        build_ipv4_interface.execute()

        ipv4_layer1 = interface1.get_children('Ipv4Layer')[0]

        ipv4_layer1.edit(Address='202.168.1.2', Gateway='202.168.1.1')

        ipv4_layer2 = interface2.get_children('Ipv4Layer')[0]

        ipv4_layer2.edit(Address='202.168.1.1', Gateway='202.168.1.2')

        ipv4_layer3 = interface3.get_children('Ipv4Layer')[0]

        ipv4_layer3.edit(Address='202.168.2.2', Gateway='202.168.2.1')

        ipv4_layer4 = interface4.get_children('Ipv4Layer')[0]

        ipv4_layer4.edit(Address='202.168.2.1', Gateway='202.168.2.2')

        clear_smart_scripter_commands()

        wizard_config, (
            throughput_config, backtoback_config, frameloss_config, latency_config) = get_benchmark_wizard_config(
            test_items=('throughput', 'backtoback', 'frameloss', 'latency'))

        # Common configuration of the RFC2544 wizard

        relate_ports(wizard_config, [self.Port_1, self.Port_2, self.Port_3, self.Port_4])

        create_streams(wizard_config, ('throughput', 'backtoback', 'frameloss', 'latency'), 'ipv4', [ipv4_layer1],
                       [ipv4_layer2], bidirectional=False, mesh_mode='1v1')

        config_address_learning([throughput_config, backtoback_config, frameloss_config, latency_config],
                                learning_frequency='once', enable_address_learning=True)

        config_latency_parameters([throughput_config, backtoback_config, frameloss_config, latency_config],
                                  latency_type='FIFO', delay_before_start_stream=2, delay_after_stop_stream=2)
        # save result file
        config_result_path([throughput_config, backtoback_config, frameloss_config, latency_config],
                           abs_path=save_result_file)

        # Configuration of RFC2544 throughput tests

        config_result_file_name(throughput_config, use_custom_result_file_name=True,
                                result_file_name='test_2554_throughput', append_timestamp=True)

        config_test_duration(throughput_config, trial_number=1, duration_mode='second', duration_count=10)

        config_frame_size_loop(throughput_config, loop_type='step', start_length=80, end_length=100, step_length=10)

        config_binary_search_parameters(throughput_config, search_mode='binary', lower_rate=1, upper_rate=100,
                                        init_rate=90, step_rate=10, resolution=1, back_off_ratio=50, acceptance_loss=0)

        # Configuration of RFC2544 back-to-back tests

        config_result_file_name(backtoback_config, use_custom_result_file_name=True,
                                result_file_name='test_2554_backtoback', append_timestamp=True)

        config_test_duration(backtoback_config, trial_number=1, duration_mode='second', duration_count=10)

        config_frame_size_loop(backtoback_config, loop_type='step', start_length=80, end_length=100, step_length=10)

        config_traffic_load_loop(backtoback_config, load_unit='percent', load_mode='custom', load_custom=(10, 20, 50))

        config_backtoback_binary_search(backtoback_config, min_duration=0.000064, duration_resolution=0.0001,
                                        accept_frame_loss=0)

        # Configuration of RFC2544 frame loss tests

        config_result_file_name(frameloss_config, use_custom_result_file_name=True,
                                result_file_name='test_2554_frameloss', append_timestamp=True)

        config_test_duration(frameloss_config, trial_number=1, duration_mode='second', duration_count=10)

        config_frame_size_loop(frameloss_config, loop_type='step', start_length=80, end_length=100, step_length=10)

        config_traffic_load_loop(frameloss_config, load_unit='percent', load_mode='random', load_min=10, load_max=50)

        # Configuration of RFC2544 latency tests

        config_result_file_name(latency_config, use_custom_result_file_name=True, result_file_name='test_2554_latency',
                                append_timestamp=True)

        config_test_duration(latency_config, trial_number=1, duration_mode='second', duration_count=10)

        config_frame_size_loop(latency_config, loop_type='step', start_length=80, end_length=100, step_length=10)

        config_traffic_load_loop(latency_config, load_unit='percent', load_mode='random', load_min=10, load_max=50)

        expand_cmd = ExpandWizardCommand(WizardConfig=wizard_config.handle)

        expand_cmd.execute()

        start_cmd = StartSmartScripterCommand()

        start_cmd.execute()

        get_state = self.sys_entry.get_children('SmartScripter')[0]

        get_state.get()

        # If the return value of get_state.State is Idle, the script stops automatically; if the return value is not
        # Idle, you need to stop the script manually

        stop_cmd = StopSmartScripterCommand()

        stop_cmd.execute()

if __name__ == '__main__':
    renix = Renix_RFC2889()
    save_result_file = 'E://renix//2889//benchmark_test'
    # if os.path.exists(save_result_file):
    #     os.remove(save_result_file)
    # os.makedirs(save_result_file)
    renix.set_renix_rfc2889_start(save_result_file)